local VERSION = "v1.01"
local Sol = LibStub("Sol")

local MAX_ITEMS = 10
local nextUpdate = nil
local needUpdate = false

ItemCounts = {}

ItemCounts.DefaultSettings = {
    enabled = true,
    minimized = false,
    framePos = nil,
    updateInterval = 0.5,
}

function ItemCounts.OnLoad(frame)
    frame:RegisterEvent("VARIABLES_LOADED")
    ItemCountsFrameMinimizeButton.tooltip = "Minimize"
end

function ItemCounts.OnEvent(frame, _event, _arg1, _arg2)
	if ( _event == "VARIABLES_LOADED" ) then
        Sol.config.CreateSlashCommand("icounts", ItemCounts.ToggleVisible)
        Sol.config.CheckSettings("ItemCounts", ItemCounts.DefaultSettings, nil, nil, true)
        
        SaveVariablesPerCharacter("ItemCounts_Items")
        if not ItemCounts_Items then
            ItemCounts_Items = {}
        end
        
        ItemCounts.RegisterWithAddonManager()
        
        --Sol.config.RestoreFrameBounds("ItemCounts", ItemCountsFrame, true)
        if ItemCounts_Settings.framePos then
            local scale = GetUIScale()
            ItemCountsFrame:ClearAllAnchors()
            ItemCountsFrame:SetAnchor("TOPLEFT", "TOPLEFT", "UIParent", 
                ItemCounts_Settings.framePos[1] / scale, 
                ItemCounts_Settings.framePos[2] / scale)
        end
        
        if ItemCounts_Settings.enabled then
            ItemCounts.Enable()
        else
            ItemCounts.Recheck()
            ItemCountsFrame:Hide()
        end
        
        if ItemCounts_Settings.minimized then
            ItemCounts.Minimize()
        end
    else
        needUpdate = true
    end
end

function ItemCounts.RegisterWithAddonManager() 
    if AddonManager then
        local addon = {
            name = "ItemCounts", 
            description = "Keeps track of the number of a specific set of items in your inventory", 
            category = "Inventory",
            version = VERSION,
            author = "Alleris",
            slashCommands = "/icounts",
            miniButton = ItemCountsMiniButton,
            icon = "Interface/Addons/ItemCounts/Textures/ItemCounts.tga",
            onClickScript = ItemCounts.ToggleVisible,
            enableScript = ItemCounts.Enable,
            disableScript = ItemCounts.Disable,
        }
        
        if AddonManager.RegisterAddonTable then
            AddonManager.RegisterAddonTable(addon)
        else
            AddonManager.RegisterAddon(addon.name, addon.description, addon.icon, addon.category, 
                addon.configFrame, addon.slashCommands, addon.miniButton, addon.onClickScript)
        end
    else
        Sol.io.Print("ItemCounts loaded")
    end
end

function ItemCounts.Enable()
    ItemCountsFrame:RegisterEvent("PLAYER_INVENTORY_CHANGED")
    ItemCountsFrame:RegisterEvent("BAG_ITEM_UPDATE")
    ItemCountsFrame:RegisterEvent("ITEMQUEUE_INSERT")
    ItemCountsFrame:RegisterEvent("ITEMQUEUE_UPDATE")
    ItemCounts.Recheck()
    ItemCounts_Settings.enabled = true
end

function ItemCounts.Disable()
    ItemCountsFrame:UnregisterEvent("PLAYER_INVENTORY_CHANGED")
    ItemCountsFrame:UnregisterEvent("BAG_ITEM_UPDATE")
    ItemCountsFrame:UnregisterEvent("ITEMQUEUE_INSERT")
    ItemCountsFrame:UnregisterEvent("ITEMQUEUE_UPDATE")
    ItemCounts_Settings.enabled = false
end

function ItemCounts.AddItem()
    local itemName = ItemCountsFrameAddText:GetText()
    if #itemName > 0 and #ItemCounts_Items < MAX_ITEMS then
        table.insert(ItemCounts_Items, itemName)
        ItemCounts.Recheck()
    elseif #ItemCounts_Items == MAX_ITEMS then
        Sol.io.Print("Cannot watch more than " .. MAX_ITEMS .. " items")
    end
    ItemCountsFrameAddText:SetText("")
end

function ItemCounts.RemoveItem(itemFrame)
    local label = _G[itemFrame:GetName() .. "NameLabel"]:GetText()
    for i, v in ipairs(ItemCounts_Items) do
        if Sol.string.StartsWith(label, v) then
            table.remove(ItemCounts_Items, i)
            ItemCounts.Recheck()
            break
        end
    end
end

function ItemCounts.Count(itemName)
    -- bag count
    local count = Sol.data.items.GetTotalBagItemCount(itemName)
    
    -- queue count
    for i = 1, 20 do
        if itemName == GetItemQueueInfo(i) then
            count = count + 1
        end
    end
    
    -- cs bag and xmuter count
    for i = 1, 55 do
        local texture, name, num = GetGoodsItemInfo(i)
        if name == itemName then
            count = count + num
        end
    end
    
    -- ammo count
    local _, _, ammoName = GetInventoryItemDurable("player", 9) -- 9 is ammo slot
    if Sol.string.StartsWith(itemName, ammoName) then
        count = count + GetInventoryItemCount("player", 9)
    end
    
    return count
end

function ItemCounts.Recheck()
    for i = 1, MAX_ITEMS do
        local itemFrame = _G["ItemCountsFrameItem" .. i]
        if ItemCounts_Items[i] then
            local label = _G[itemFrame:GetName() .. "NameLabel"]
            local count = ItemCounts.Count(ItemCounts_Items[i])
            label:SetText(string.format("%s: %d", ItemCounts_Items[i], count))
            itemFrame:Show()
        else
            itemFrame:Hide()
        end
    end
    local x,y = ItemCountsFrame:GetSize()
    ItemCountsFrame:SetSize(x, #ItemCounts_Items * 20 + 60)
end

function ItemCounts.Minimize()
    ItemCountsFrame:Disable()
    ItemCountsFrameBG:Hide()
    ItemCountsFrameLabel:Hide()
    ItemCountsFrameAddButton:Hide()
    ItemCountsFrameAddText:Hide()
    ItemCountsFrameCloseButton:Hide()
    ItemCountsFrameMinimizeButton:Hide()
    for i = 1, MAX_ITEMS do
        _G["ItemCountsFrameItem" .. i .. "RemoveButton"]:Hide()
    end
    ItemCounts_Settings.minimized = true
    
    --Sol.animation.Fade("ItemCounts", ItemCountsFrameBG, 0, nil, 0.2)
end

function ItemCounts.Restore()
    ItemCountsFrame:Enable()
    ItemCountsFrameBG:Show()
    ItemCountsFrameLabel:Show()
    ItemCountsFrameAddButton:Show()
    ItemCountsFrameAddText:Show()
    ItemCountsFrameCloseButton:Show()
    ItemCountsFrameMinimizeButton:Show()
    for i = 1, MAX_ITEMS do
        _G["ItemCountsFrameItem" .. i .. "RemoveButton"]:Show()
    end
    ItemCounts_Settings.minimized = false
    
    --Sol.animation.Fade("ItemCounts", ItemCountsFrameBG, 1, nil, 0.2)
end

function ItemCounts.ToggleVisible()
    if ItemCountsFrame:IsVisible() and not ItemCounts_Settings.minimized then
        ItemCountsFrame:Hide()
        ItemCountsUpdateFrame:Hide()
    elseif ItemCounts_Settings.minimized then
        ItemCounts.Restore()
        ItemCountsUpdateFrame:Show()
    else
        ItemCountsFrame:Show()
        ItemCountsUpdateFrame:Show()
    end
end

function ItemCounts.StartMoving(frame)
    frame:StartMoving("CENTER")
end

function ItemCounts.StopMoving(frame)
    frame:StopMovingOrSizing()
    ItemCounts_Settings.framePos = { frame:GetPos() }
    --Sol.config.SaveFrameBounds("ItemCounts", this, true)
end

function ItemCounts_OnUpdate()
    if needUpdate and (not nextUpdate or nextUpdate <= GetTime()) then
        nextUpdate = GetTime() + ItemCounts_Settings.updateInterval
        needUpdate = false
        ItemCounts.Recheck()        
    end
end

function ItemCounts.OnEditFocusLost(txtBox)
    Sol.hooks.UnHook("ItemCounts", "BagItemButton_OnClick")
end

function ItemCounts.OnEditFocusGained(txtBox)
    Sol.hooks.Hook("ItemCounts", "BagItemButton_OnClick", ItemCounts.BagItemButton_OnClick)
end

function ItemCounts.BagItemButton_OnClick(frame, button, ignoreShift)
    if IsShiftKeyDown() then
        local _, _, name = GetBagItemInfo(frame:GetID())
        ItemCountsFrameAddText:SetText(name)
        ItemCounts.AddItem()
    else
        Sol.hooks.GetOriginalFn(Streamline.Strings.AddonName, "BagItemButton_OnClick")(frame, button, ignoreShift)
    end
end
